package com.yunxi.core.base;

import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.regex.Pattern;

/**
 * 数字处理工具类
 *
 */
public class NumUtils {

    /**
     * 判断当前值是否为整数
     *
     * @param value
     * @return
     */
    public static boolean isInteger(Object value) {
        if (StringUtils.isEmpty(value)) {
            return false;
        }
        String mstr = value.toString();
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(mstr).matches();
    }

    /**
     * 判断当前值是否为数字(包括小数)
     *
     * @param value
     * @return
     */
    public static boolean isDigit(Object value) {
        if (StringUtils.isEmpty(value)) {
            return false;
        }
        String mstr = value.toString();
        return NumberUtils.isNumber(mstr);
    }

    /**
     * 将数字格式化输出
     *
     * @param value
     *            需要格式化的值
     * @param precision
     *            精度(小数点后的位数)
     * @return
     */
    public static String format(Object value, Integer precision) {
        Double number = 0.0;
        if (NumUtils.isDigit(value)) {
            number = new Double(value.toString());
        }
        precision = (precision == null || precision < 0) ? 2 : precision;
        BigDecimal bigDecimal = new BigDecimal(number);
        return bigDecimal.setScale(precision, BigDecimal.ROUND_HALF_UP)
                .toString();
    }

    /**
     * 将数字格式化输出
     *
     * @param value
     * @return
     */
    public static String format(Object value) {
        return NumUtils.format(value, 2);
    }

    /**
     * 将值转成Integer型，如果不是整数，则返回0
     *
     * @param value
     * @param replace
     *            如果为0或者null，替换值
     * @return
     */
    public static Integer parseInteger(Object value, Integer replace) {
        if (!NumUtils.isInteger(value)) {
            return replace;
        }
        return new Integer(value.toString());
    }

    /**
     * 将值转成Integer型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static Integer parseInteger(Object value) {
        return NumUtils.parseInteger(value, 0);
    }

    /**
     * 将值转成Long型
     *
     * @param value
     * @param replace
     *            如果为0或者null，替换值
     * @return
     */
    public static Long parseLong(Object value, Long replace) {
        if (!NumUtils.isInteger(value)) {
            return replace;
        }
        return new Long(value.toString());
    }

    /**
     * 将值转成Long型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static Long parseLong(Object value) {
        return NumUtils.parseLong(value, 0L);
    }

    /**
     * 将值转成Double型
     *
     * @param value
     * @param replace
     *            replace 如果为0或者null，替换值
     * @return
     */
    public static Double parseDouble(Object value, Double replace) {
        if (!NumUtils.isDigit(value)) {
            return replace;
        }
        return new Double(value.toString());
    }

    /**
     * 将值转成Double型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static Double parseDouble(Object value) {
        return NumUtils.parseDouble(value, 0.0);
    }

    /**
     * 将char型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(char value) {
        byte[] bt = new byte[2];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将short型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(short value) {
        byte[] bt = new byte[2];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将int型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(int value) {
        byte[] bt = new byte[4];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将long型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(long value) {
        byte[] bt = new byte[8];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将short型数据插入到指定索引的字节数组中
     *
     * @param index
     *            索引
     * @param values
     *            字节数组
     * @param value
     *            需要插入的值
     */
    public static void insert(int index, byte[] values, short value) {
        byte[] bt = NumUtils.toBytes(value);
        System.arraycopy(bt, 0, values, index, 2);
    }

    /**
     * 将int型数据插入到指定索引的字节数组中
     *
     * @param index
     *            索引
     * @param values
     *            字节数组
     * @param value
     *            需要插入的值
     */
    public static void insert(int index, byte[] values, int value) {
        byte[] bt = NumUtils.toBytes(value);
        System.arraycopy(bt, 0, values, index, 4);
    }

    /**
     * 将long型数据插入到指定索引的字节数组中
     *
     * @param index
     *            索引
     * @param values
     *            字节数组
     * @param value
     *            需要插入的值
     */
    public static void insert(int index, byte[] values, long value) {
        byte[] bt = NumUtils.toBytes(value);
        System.arraycopy(bt, 0, values, index, 8);
    }

    /**
     * 将字节转换成整型
     *
     * @param value
     *            字节类型值
     * @return
     */
    public static int byteToInt(byte value) {
        if (value < 0) {
            return value + 256;
        }
        return value;
    }


    public static Double sub(Double v1, Double v2) {
        BigDecimal b1 = new BigDecimal(v1.toString());
        BigDecimal b2 = new BigDecimal(v2.toString());
        return new Double(b1.subtract(b2).doubleValue());
    }


    public static Float div(String v1, String v2, Integer scale ) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.divide(b2, scale , BigDecimal.ROUND_HALF_UP).floatValue();
    }
}
